﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using Common.Models;

namespace Common
{
    /// <summary>
    /// 画图
    /// </summary>
    public class Draw
    {
        /// <summary>
        /// 根据ouput和传入的Graphics实例来画图
        /// </summary>
        /// <param name="output"></param>
        /// <param name="g"></param>
        public static void DrawPattern(Output output, Graphics g)
        {

            if (output == null) return;
            //try
            //{

            #region 设置画图参数
            //设置质量

            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            //填充背景颜色
            //g.Clear(Form1.DefaultBackColor);
            g.Clear(Color.White);

            //缩小10倍
            g.ScaleTransform(0.1f, 0.1f);


            Brush myBrush = new SolidBrush(Color.Black);//毛胚颜色

            var clientRectangle = new Rectangle(0,0, (int)output.Width, (int)output.Length);

            //板材填充颜色
            LinearGradientBrush myBrush1 = new LinearGradientBrush(clientRectangle, Color.White, Color.White, LinearGradientMode.Horizontal);

            //毛胚填充颜色
            LinearGradientBrush myBrush2 = new LinearGradientBrush(clientRectangle, Color.Black, Color.White, LinearGradientMode.Horizontal);

            //文字颜色
            LinearGradientBrush myBrush3 = new LinearGradientBrush(clientRectangle, Color.Blue, Color.Blue, LinearGradientMode.Horizontal);


            Font myFont = new Font("微软雅黑", 100);

            Pen myPen = new Pen(myBrush, 10);
            Pen myPen2 = new Pen(Color.Blue);
            Pen myPen3 = new Pen(Color.Green);
            Pen myPen4 = new Pen(Color.Black);
            Pen myPen5 = new Pen(Color.Black);


            #endregion

            //当前正在画的毛坯，记录起来，直到下一种毛坯
            var diaType = -1;
            //直径-毛坯号键值对
            var diaDic = new Dictionary<double, double>();
            for (int j = 0; j < output.Diameter.Length; j++)
            {
                diaDic[output.Diameter[j]] = j + 1;
            }
            //在这处理每一排样方式下的说明
            var str1 = new StringBuilder();
            str1.AppendLine($"长:{output.Length}");
            str1.AppendLine($"宽:{output.Width}");
            str1.AppendLine("毛坯种类数:" + output.Diameter.Length);
            str1.Append("直径:");
            for (int index = 0; index < output.Diameter.Length; index++)
            {
                var item = output.Diameter[index];
                str1.Append($" {item}");
                if (index == 30)
                {
                    str1.Append("\r\n");
                }
            }
            str1.AppendLine();
            str1.Append("需求:");
            for (int index = 0; index < output.Demand.Length; index++)
            {
                var item = output.Demand[index];
                str1.Append($" {item}");
                if (index == 30)
                {
                    str1.Append("\n");
                }
            }
            str1.AppendLine();

            //排样方式图左边距
            int marginLeft = 600;
            //排样方式图上边距
            int marginTop = 1500;
            g.DrawString(str1.ToString(), myFont, myBrush3, marginLeft, 200);


            int xx = 0;//排样方式图x坐标变化量
            int yy = 2000;//排样方式图y坐标变化量
            int n2 = output.Plates.Count;
            for (int kk = 0; kk < n2; kk++)
            {//遍历排样的所有方式

                xx = kk % 5 * (int)(output.Length + 300);
                yy = kk / 5 * (int)(output.Width + 1100);

                int x, y, l, w;
                x = marginLeft + xx + output.Plates[kk][2][0][1];
                y = marginTop + yy + output.Plates[kk][2][0][2];
                l = output.Plates[kk][2][0][3];
                w = output.Plates[kk][2][0][4];

                g.DrawRectangle(myPen4, x, y, l, w);
                g.FillRectangle(myBrush1, x, y, l, w);
                //显示每个排样方式下的说明
                var sb = new StringBuilder();
                sb.AppendLine($"({kk + 1})");
                sb.AppendLine($"{"板材张数："}{(output.PlateNum?[kk]).ToString()}");
                var isUses = output.DiaNum[kk].Select(o => o != 0).ToArray();
                sb.AppendFormat("{0}", "毛坯序号：");
                for (int index = 0; index < output.Diameter.Length; index++)
                {
                    if (isUses[index])
                    {
                        sb.AppendFormat("{0,-3}", index + 1);
                    }
                }
                sb.AppendLine();
                sb.AppendFormat("{0}", "毛坯数量：");
                for (int index = 0; index < output.DiaNum[kk].Length; index++)
                {
                    var item = output.DiaNum[kk][index];
                    if (isUses[index])
                    {
                        sb.AppendFormat("{0,-3}", item);
                    }
                }
                sb.AppendLine();
                sb.AppendLine(output.PlateRemark?[kk]);
                g.DrawString(sb.ToString(), myFont, myBrush3, x, y + w + 50);

                //重置
                diaType = -1;

                #region 画椭圆
                int ellipseSum = output.Plates[kk][0].Count();
                if (ellipseSum > 0)
                {
                    for (int j = 0; j < ellipseSum; j++)
                    {
                        int ellipse = output.Plates[kk][0][j][6];
                        for (int k = 0; k < ellipse; k++)
                        {
                            if (output.Plates[kk][0][j][5] == 1)
                            {
                                x = marginLeft + xx + output.Plates[kk][0][j][1] + k * output.Plates[kk][0][j][3];
                                y = marginTop + yy + output.Plates[kk][0][j][2];
                            }
                            else if (output.Plates[kk][0][j][5] == 2)
                            {
                                x = marginLeft + xx + output.Plates[kk][0][j][1];
                                y = marginTop + yy + output.Plates[kk][0][j][2] + k * output.Plates[kk][0][j][4];
                            }
                            l = output.Plates[kk][0][j][3];
                            w = output.Plates[kk][0][j][4];
                            g.DrawEllipse(myPen, x, y, l, w);
                            //在第一个毛坯上画毛坯号
                            var type = (int)diaDic[output.Plates[kk][0][j][3]];
                            if (diaType != type)
                            {
                                diaType = type;
                                g.DrawString(diaType.ToString(), myFont, myBrush3, x, y);
                            }
                        }

                    }
                }
                #endregion
                #region 画直线
                int lineSum = output.Plates[kk][1].Count();
                if (lineSum > 0)
                {
                    for (int j = 0; j < lineSum; j++)
                    {
                        x = marginLeft + xx + output.Plates[kk][1][j][1];
                        y = marginTop + yy + output.Plates[kk][1][j][2];
                        l = marginLeft + xx + output.Plates[kk][1][j][3];
                        w = marginTop + yy + output.Plates[kk][1][j][4];
                        g.DrawLine(myPen, x, y, l, w);
                    }
                }
                #endregion
                #region 画矩形
                int rectangleSum = output.Plates[kk][2].Count();
                if (rectangleSum > 0)
                {
                    for (int j = 0; j < rectangleSum; j++)
                    {
                        int rectangle = output.Plates[kk][2][j][6];
                        for (int k = 0; k < rectangle; k++)
                        {
                            if (output.Plates[kk][2][j][5] == 1)
                            {
                                x = marginLeft + xx + output.Plates[kk][2][j][1] + k * output.Plates[kk][2][j][3];
                                y = marginTop + yy + output.Plates[kk][2][j][2];
                            }
                            else if (output.Plates[kk][2][j][5] == 2)
                            {
                                x = marginLeft + xx + output.Plates[kk][2][j][1];
                                y = marginTop + yy + output.Plates[kk][2][j][2] + k * output.Plates[kk][2][j][4];
                            }
                            l = output.Plates[kk][2][j][3];
                            w = output.Plates[kk][2][j][4];
                            g.DrawRectangle(myPen, x, y, l, w);
                        }
                    }
                }
                #endregion

            }
            var str2 = output.Result;
            str2 = "利用率:" + output.UtilizationRate;
            str2 += "\r\n板材使用张数:" + output.TotalPlateNum;

            g.DrawString(str2, myFont, myBrush3, marginLeft, 3000 + yy + (int)output.Width);
            g.Dispose();

            //}
            //catch (Exception e)
            //{
            //    MessageBox.Show("数据错误：" + e.Message);
            //}

        }
        /// <summary>
        /// 根据ouput里面的数据画出一个图片
        /// </summary>
        /// <returns></returns>
        public static Bitmap OutputToBitmap(Output output)
        {
            var height = (3400 + (int)Math.Ceiling(output.Plates.Count / 5.0) * (int)output.Width * 2) / 10;
            var width = (int)output.Length * 6 / 10;
            var bmp = new Bitmap(width, height);
            using (var g = Graphics.FromImage(bmp))
            {
                DrawPattern(output, g);
            }
            return bmp;
        }
    }
}
